home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / snip0493.zip / INITVARS.C < prev    next >
C/C++ Source or Header  |  1993-04-05  |  5KB  |  140 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdarg.h>
  4. #include <string.h>
  5. #include <ctype.h>
  6. #include <assert.h>
  7.  
  8. /**** init_globals(fp, names, types, ...)
  9. **
  10. ** public domain by Raymond Gardner     Sept. 1991
  11. **
  12. ** fp is a FILE * to the (already fopen'ed) file containing
  13. **      initialization data
  14. **  names is a space-separated list of names of globals (as they
  15. **      are to appear in the data file)
  16. **  types is a list of datatype characters, corresponding to names
  17. **      i  for a pointer to integer
  18. **      s  for a pointer to string (already allocated char array)
  19. **      p  for a pointer to pointer to char (space will be malloc'd)
  20. **    (NOTE: no whitespace allowed in types !!)
  21. **  followed by var arg list of pointers to variables to init
  22. */
  23.  
  24. #define LNSZ 256
  25.  
  26. int init_globals(FILE *fp, char *names, char *types, ...)
  27. {
  28.     char ln[LNSZ];
  29.     char *p;
  30.     va_list arglist;
  31.     char *namep, *typep, name[40], *e;
  32.     void *argp;
  33.     int k;
  34.  
  35.     while ( fgets(ln, LNSZ, fp) ) {             /* read init file */
  36.         while ( isspace(ln[0]) )            /* drop leading whitespace */
  37.             memmove(ln, ln+1, strlen(ln));
  38.         if ( ln[0] == 0 )                       /* skip if blank line */
  39.             continue;
  40.         p = strchr(ln, '=');                    /* find equal sign */
  41.         if ( p == NULL )                        /* error if none */
  42.             return -1;  /* or continue; */
  43.         while ( p > ln && isspace(p[-1]) ) {    /* remove whitespace */
  44.             memmove(p-1, p, strlen(p-1));       /*   before = sign */
  45.             --p;
  46.         }
  47.         *p++ = 0;                               /* plug EOS over = sign */
  48.         while ( isspace(p[0]) )             /* remove leading space on */
  49.             memmove(p, p+1, strlen(p));         /*    init string */
  50.         k = strlen(p) - 1;                      /* init string length */
  51.         if ( k < 1 )
  52.             return -1;
  53.  
  54.         if ( p[k] != '\n' )             /* if '\n' is missing, input */
  55.             return -1;                  /*   exceeded buffer; error return */
  56.         p[k] = 0;                       /* plug EOS over newline */
  57.  
  58.         va_start(arglist, types);       /* setup for arglist search */
  59.  
  60.         namep = names;                  /* init ptr to var names */
  61.         typep = types;                  /* init ptr to var types */
  62.         while ( *namep == ' ' )         /* skip blanks before namelist */
  63.             ++namep;
  64.         while ( *typep ) {          /* while any typelist items left...*/
  65.  
  66.             argp = (void *)va_arg(arglist, void *); /* get var arg */
  67.  
  68.             k = strcspn(namep, " ");        /* length of namelist entry */
  69.             memmove(name, namep, k);        /* put into name hold area */
  70.             name[k] = 0;                    /* terminate it */
  71.             if ( strcmp(name, ln) != 0 ) { /* if it doesn't match... */
  72.                 namep += k;                 /* get next name */
  73.                 while ( *namep == ' ' )
  74.                     ++namep;
  75.                 ++typep;                    /* get next type */
  76.             } else {                        /* else name is found... */
  77.                 if ( *typep == 'i' ) {      /* if it's an int, init it */
  78.                     *(int *)argp = atoi(p);
  79.                 } else if ( *typep == 's' || *typep == 'p' ) {
  80.                     if ( *p == '"' ) {      /* is string in quotes? */
  81.                         ++p;                /* skip leading quote, and */
  82.                         e = strchr(p, '"'); /* look for trailing quote */
  83.                         if ( e )            /* terminate string if found */
  84.                             *e = 0;
  85.                     }
  86.                     if ( *typep == 'p' ) {      /* if it's a char *ptr */
  87.                         e = malloc(strlen(p) + 1); /* get space */
  88.                         if ( e == 0 ) {         /* error if no space */
  89.                             return -1; /* call va_end(arglist); first? */
  90.                         }
  91.                         *(char **)argp = e;
  92.                         strcpy(*(char **)argp, p);  /* copy in string */
  93.                     } else                          /* must be char array */
  94.                         strcpy(argp, p);            /* copy in string */
  95.                 } else {
  96.                     return -1;                      /* bad type */
  97.                 }
  98.                 break;              /* break search; get next line */
  99.             }
  100.         }
  101.         va_end(arglist);
  102.     }
  103.     return 0;
  104. }
  105. #ifdef TEST
  106.  
  107. int foo;
  108. char bar[80];
  109. int baz;
  110. char *quux;
  111.  
  112. int main(int argc, char **argv)
  113. {
  114.     FILE *fp;
  115.     int k;
  116.  
  117.     if ( argc < 2 ) {
  118.         fprintf(stderr, "missing arg\n");
  119.         exit(1);
  120.     }
  121.  
  122.     fp = fopen(argv[1], "r");
  123.     assert(fp);
  124.     k = init_globals(fp, "foo bar baz quux", "isip",
  125.         &foo, bar, &baz, &quux);
  126.     printf("k: %d\n", k);
  127.     printf("foo: %d\nbar: <%s>\nbaz: %d\nquux: <%s>\n",
  128.         foo, bar, baz, quux);
  129.     fclose(fp);
  130.  
  131.     return 0;
  132. }
  133. #endif
  134. /* test data file:
  135. foo=123
  136. bar = "a test"
  137.    baz     =  456
  138. quux=    what is this
  139. */
  140.